package com.huike.clues.service.impl;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huike.clues.domain.SysRole;
import com.huike.clues.domain.SysRoleDept;
import com.huike.clues.domain.SysRoleMenu;
import com.huike.clues.domain.SysUserRole;
import com.huike.clues.domain.dto.SysRoleDeptDTO;
import com.huike.clues.domain.dto.SysRoleMenuDTO;
import com.huike.clues.domain.vo.SysRoleVo;
import com.huike.clues.mapper.SysRoleDeptMapper;
import com.huike.clues.mapper.SysRoleMenuMapper;
import com.huike.clues.mapper.SysUserRoleMapper;
import com.huike.common.exception.BaseException;
import com.huike.common.exception.CustomException;
import com.huike.common.utils.DateUtils;
import com.huike.common.utils.SecurityUtils;
import com.huike.common.utils.bean.BeanUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.stereotype.Service;
import com.huike.common.core.domain.entity.SysRoleDTO;
import com.huike.common.utils.StringUtils;
import com.huike.common.utils.spring.SpringUtils;
import com.huike.clues.mapper.SysRoleMapper;
import com.huike.clues.service.ISysRoleService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;

/**
 * 角色 业务层处理
 * 
 * 
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService
{

    @Resource
    private  SysRoleMapper roleMapper;

    private final SysUserRoleMapper sysUserRoleMapper;

    private final SysRoleMenuMapper sysRoleMenuMapper;

    private final SysRoleDeptMapper sysRoleDeptMapper;


    /**
     * 查询所有角色
     *
     * @return 角色列表
     */
    @Override
    public List<SysRoleDTO> selectRoleAll()
    {
        return SpringUtils.getAopProxy(this).selectRoleList(new SysRoleDTO());
    }

    /**
     * 根据条件分页查询角色数据
     *
     * @param role 角色信息
     * @return 角色数据集合信息
     */
    @Override
    public List<SysRoleDTO> selectRoleList(SysRoleDTO role)
    {
        return roleMapper.selectRoleList(role);
    }

    /**
     * 根据用户ID获取角色选择框列表
     *
     * @param userId 用户ID
     * @return 选中角色ID列表
     */
    @Override
    public List<Integer> selectRoleListByUserId(Long userId)
    {
        return roleMapper.selectRoleListByUserId(userId);
    }
    /**
     * 根据用户ID查询权限
     *
     * @param userId 用户ID
     * @return 权限列表
     */
    @Override
    public Set<String> selectRolePermissionByUserId(Long userId)
    {
        List<SysRoleDTO> perms = roleMapper.selectRolePermissionByUserId(userId);
        Set<String> permsSet = new HashSet<>();
        for (SysRoleDTO perm : perms)
        {
            if (StringUtils.isNotNull(perm))
            {
                permsSet.addAll(Arrays.asList(perm.getRoleKey().trim().split(",")));
            }
        }
        return permsSet;
    }

    /**
     * 新增角色
     *
     * @param sysRoleDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertUser(SysRoleDTO sysRoleDTO) {

        int rows = roleMapper.insertRole(sysRoleDTO);

        Long[] menuIds = sysRoleDTO.getMenuIds();
        Long[] deptIds = sysRoleDTO.getDeptIds();

        if (StringUtils.isNotNull(menuIds)) {
            List<SysRoleMenuDTO> list = new ArrayList<>();

            for (Long menuId : menuIds) {
                SysRoleMenuDTO sr = new SysRoleMenuDTO();
                sr.setRoleId(sysRoleDTO.getRoleId());
                sr.setMenuId(menuId);
                list.add(sr);
            }

            if (list.size() > 0) {
                sysRoleMenuMapper.batchRoleMenu(list);
            }

        }
        if (StringUtils.isNotNull(deptIds)) {
            List<SysRoleDeptDTO> list = new ArrayList<>();
            for (Long deptId : deptIds) {
                SysRoleDeptDTO sd = new SysRoleDeptDTO();
                sd.setRoleId(sysRoleDTO.getRoleId());
                sd.setDeptId(deptId);
                list.add(sd);
            }
            if (list.size() > 0) {
                sysRoleDeptMapper.batchRoleDept(list);
            }

        }

        return rows;
    }

    /**
     * 根据id查询角色
     *
     * @param roleId
     * @return
     */
    @Override
    public SysRoleVo selectByRoleId(Long roleId) {
        SysRole sysRole = roleMapper.selectById(roleId);
        if (sysRole == null) {
            return null;
        }
        SysRoleVo sysRoleVo = new SysRoleVo();
        BeanUtils.copyBeanProp(sysRoleVo, sysRole);
        sysRoleVo.setDeptCheckStrictly(true);
        if (sysRole.getDeptCheckStrictly() == 0) {
            sysRoleVo.setDeptCheckStrictly(false);
        }
        sysRoleVo.setMenuCheckStrictly(true);
        if (sysRole.getMenuCheckStrictly() == 0) {
            sysRoleVo.setMenuCheckStrictly(false);
        }

        // TODO  boolean admin 根据什么判断
        sysRoleVo.setAdmin(sysRole.getRoleId() != null && 1L == sysRole.getRoleId());
        //
        sysRoleVo.setRoleSort(sysRole.getRoleSort()+"");
        // sysRoleVo.setRoleSort(String.valueOf(sysRole.getRoleSort()));
        //todo 待测试
        LambdaQueryWrapper<SysRoleMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRoleMenu::getRoleId,sysRole.getRoleId());
        List<SysRoleMenu> sysRoleMenus = sysRoleMenuMapper.selectList(wrapper);
        List<Long> menuIdList = new ArrayList<>();
        // List<Long> menuIdList = sysRoleMenus.stream().map(sysRoleMenu -> {
        //     Long id;
        //     id = sysRoleMenu.getMenuId();
        //     return id;
        //     // return sysRoleMenu.getMenuId();
        // }).collect(Collectors.toList());
        for (SysRoleMenu sysRoleMenu : sysRoleMenus) {
            menuIdList.add(sysRoleMenu.getMenuId());
        }

        Long[] menuIds = menuIdList.toArray(new Long[menuIdList.size()]);

        sysRoleVo.setMenuIds(menuIds);
        //部门id
        LambdaQueryWrapper<SysRoleDept> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.eq(SysRoleDept::getRoleId,sysRole.getRoleId());
        List<SysRoleDept> sysRoleDepts = sysRoleDeptMapper.selectList(wrapper2);
        List<Long> deptIdList = new ArrayList<>();
        for (SysRoleDept sysRoleDept : sysRoleDepts) {
            deptIdList.add(sysRoleDept.getDeptId());
        }

        Long[] deptIds = deptIdList.toArray(new Long[deptIdList.size()]);

        sysRoleVo.setDeptIds(deptIds);

        return sysRoleVo;
    }

    /**
     * 角色修改
     *
     * @param sysRoleDTO
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateRoleById(SysRoleDTO sysRoleDTO) {

        SysRole sysRole = new SysRole();
        BeanUtils.copyBeanProp(sysRole, sysRoleDTO);

        sysRole.setMenuCheckStrictly(1);
        if (!sysRoleDTO.isMenuCheckStrictly()) {
            sysRole.setMenuCheckStrictly(0);
        }
        sysRole.setDeptCheckStrictly(1);
        if (!sysRoleDTO.isDeptCheckStrictly()) {

            sysRole.setDeptCheckStrictly(0);
        }
        sysRole.setRoleSort(Integer.parseInt(sysRoleDTO.getRoleSort()));

        // TODO 修改时间 修改人
        sysRole.setUpdateBy(SecurityUtils.getUsername());
        sysRole.setUpdateTime(DateUtils.getNowDate());

        int rows;
        // TODO 权限判定
        // if (sysRoleDTO.isAdmin() && !"admin".equals(SecurityUtils.getUsername())) {
        //     return 0;
        // }else {
        if (StringUtils.isNotNull(sysRoleDTO.getRoleId()) && sysRoleDTO.isAdmin()) {
            throw new CustomException("不允许操作超级管理员角色");
        }
        rows = roleMapper.updateById(sysRole);
        // }

        //删除角色菜单关联信息
        sysRoleMenuMapper.deleteRoleMenuByRoleId(sysRoleDTO.getRoleId());
        //删除角色部门
        sysRoleDeptMapper.deleteRoleDeptByRoleId(sysRoleDTO.getRoleId());

        Long[] menuIds = sysRoleDTO.getMenuIds();
        if (StringUtils.isNotNull(menuIds)) {
            List<SysRoleMenuDTO> list = new ArrayList<>();

            for (Long menuId : menuIds) {
                SysRoleMenuDTO sr = new SysRoleMenuDTO();
                sr.setRoleId(sysRoleDTO.getRoleId());
                sr.setMenuId(menuId);
                list.add(sr);
            }

            if (list.size() > 0) {
                sysRoleMenuMapper.batchRoleMenu(list);
            }

        }
        Long[] deptIds = sysRoleDTO.getDeptIds();
        if (StringUtils.isNotNull(deptIds)) {
            List<SysRoleDeptDTO> list = new ArrayList<>();
            for (Long deptId : deptIds) {
                SysRoleDeptDTO sd = new SysRoleDeptDTO();
                sd.setRoleId(sysRoleDTO.getRoleId());
                sd.setDeptId(deptId);
                list.add(sd);
            }
            if (list.size() > 0) {
                sysRoleDeptMapper.batchRoleDept(list);
            }

        }
        return rows;
    }

    /**
     * 角色状态修改
     *
     * @param sysRoleDTO
     * @return
     */
    @Override
    public int updateRoleStatusById(SysRoleDTO sysRoleDTO) {
        //TODO 权限判定 修改admin的状态 用户是否为admin  暂不确定
        SysRole sysRole = new SysRole();
        BeanUtils.copyBeanProp(sysRole, sysRoleDTO);
        if (StringUtils.isNotNull(sysRoleDTO.getRoleId()) && sysRoleDTO.isAdmin()) {
            throw new CustomException("不允许操作超级管理员角色");
        }
        // if (sysRoleDTO.isAdmin() && !"admin".equals(SecurityUtils.getUsername())) {
        //     return 0;
        // }else {
           return  roleMapper.updateById(sysRole);
        // }
    }

    /**
     * 角色删除
     *
     * @param roleIds
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteBatch(Long[] roleIds) {

        for (Long roleId : roleIds) {
            SysRoleDTO sysRoleDTO = new SysRoleDTO();
            sysRoleDTO.setRoleId(roleId);
            if (StringUtils.isNotNull(sysRoleDTO.getRoleId()) && sysRoleDTO.isAdmin()) {
                throw new CustomException("不允许操作超级管理员角色");
            }
        }
        List<SysUserRole> list = sysUserRoleMapper.list(roleIds);
        if (StringUtils.isNotEmpty(list)) {
            throw new CustomException("角色已分配，无法删除");
        }
        sysRoleMenuMapper.deleteRoleMenu(roleIds);
        sysRoleDeptMapper.deleteRoleDept(roleIds);
        return roleMapper.deleteRoleByIds(roleIds);
    }
}
